
/*------------------------------------------------------------------------
 *  Copyright (C) 2010  Luis M. de la Cruz
 *
 *  This file is part of TUNA
 *
 *  TUNA is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  TUNA is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ------------------------------------------------------------------------*/

#ifndef _INOUT_H_
#define _INOUT_H_

#include "Tuna.hpp"
#include "Storage/DiagonalMatrix.hpp"

#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>

namespace Tuna {

/*!
 ***************************************************************************
 * \namespace InOut
 * Tools for writting and reading to and from files.
 ***************************************************************************
 *  \author Luis M. de la Cruz [ Sun Mar 23 15:03:47 GMT 2008 ]
 ***************************************************************************
 */
  namespace InOut {

    /*!
     * Write ScalarFields(1D, 2D, 3D) in ASCII format: x, y, z, field for Parallel
     */
    template<class T_sfield>
    void writeToFileP(T_sfield&, int, string, 
		     double dx, double Lx,
		     double dy = 1, double Ly = 0,
		     double dz = 1, double Lz = 0,
		     int w = 5);
    /*!
     * Write ScalarFields(1D, 2D and 3D) in OpenDX format (Parallel)
     */
    template<class T_sfield>
    void writeToFile_DXP(T_sfield& scf, int number, string filename,
			 double dx = 1, double Lx = 0,
			 double dy = 1, double Ly = 0,
			 double dz = 1, double Lz = 0,
			 int w = 5);
    /*!
     * Write ScalarFields(1D, 2D, 3D) in ASCII format: x, y, z, field
     */
    template<class T_sfield>
    void writeToFile(T_sfield&, int, string, 
		     double dx, double dy = 1, double dz = 1, int w = 5);

    /*!
     * Read files written by the above writeFile() function
     */
    template<class T_sfield>
    void readFromFile(T_sfield&, int, string, 
		      double dx, double dy = 1, double dz = 1, int w = 5);

    /*!
     * Write ScalarFields(1D, 2D, 3D) in ASCII format: field
     * This function doesn't store dx, dy and dz.
     */
    template<class T_sfield>
    void writeToFile(T_sfield&, int, string, int w = 5);

    /*!
     * Read files written by the above writeFile() function
     * This function doesn't read dx, dy and dz.
     */
    template<class T_sfield>
    void readFromFile(T_sfield&, int, string, int w = 5);

    /*!
     * Write ScalarFields(1D, 2D and 3D) in OpenDX format
     */
    template<class T_sfield>
    void writeToFile_DX(T_sfield&, int, string,
			double dx, double dy = 1, double dz = 1, int w = 5);

    /*!
     * Write ScalarFields(2D) that are components of 2D velocity 
     * in OpenDX format (Parallel)
     */
    template<class T_sfield>
    void writeToFile_DXP(T_sfield& scf, T_sfield& , int number, string filename,
			 double dx = 1, double Lx = 0,
			 double dy = 1, double Ly = 0,
			 int w = 5);
    /*!
     * Write ScalarFields(2D) that are components of 2D velocity in OpenDX format 
     */
    template<class T_sfield>
    void writeToFile_DX(T_sfield&, T_sfield&, int, string, 
			double dx = 1, double dy = 1,
			int w = 5);

    /*!
     * Write ScalarFields(3D) that are components of a 3D vector 
     * field in OpenDX format 
     */
    template<class T_sfield>
    void writeToFile_DX(T_sfield&, T_sfield&, T_sfield&, int, string, 
			double dx = 1, double dy = 1, double dz = 1,
			int w = 5);

    /*!
     * Write ScalarField(1D, 2D y 3D) in OpenDX format for NonUniform Meshes 
     */
    template<class T_sfield, class T_mesh>
    void writeToFile_DX(T_sfield&, int, string, T_mesh& m, int w = 5);

    /*!
     * Write ScalarFields(2D) that are components of a 2D vector field in OpenDX 
     * format for NonUniform Meshes
     */
    template<class T_sfield, class T_mesh>
    void writeToFile_DX(T_sfield &scf1, T_sfield &scf2, 
			       int number, string filename, T_mesh &m, int w = 5);

    /*!
     * Write ScalarFields(3D) that are components of a 3D vector field in OpenDX 
     * format for NonUniform Meshes
     */
    template<class T_sfield, class T_mesh>
    void writeToFile_DX(T_sfield &scf1, T_sfield &scf2, T_sfield &scf3, 
			       int number, string filename, T_mesh &m, int w = 5);
    /*!
     * Amiramesh file format
     * This function writes amira mesh format for the 3D case
     */
    template<class T_sfield>
    void writeToFile_AM(T_sfield& scf, int number, string filename,
			double dx = 1, double dy = 1, double dz = 1,
			int w = 5);

    /*!
     * Auxiliar function for Partracking tests
     */
    template<class T_sfield>
    void readFromFile_1(T_sfield&, T_sfield&, int, string, int w = 5);

    /*!
     * Auxiliar function for Partracking tests
     */
    template<class T_sfield>
    void readFromFile_2(T_sfield&, T_sfield&, T_sfield&,
			int, string, int w = 5);

    /*!
     * Write out the Diagonal Matrices to a file. (1D, 2D and 3D)
     */
    template<class Type, int Dim>
    ostream& operator<<(ostream&, const DiagonalMatrix<Type, Dim>&);
      
  } //InOut namespace

} // Tuna namespace

#include "../src/Utils/inout.cpp"

#endif //_INOUT_H_



